unit sci.sort;

interface

uses
  Windows, SysUtils, Generics.Defaults, Generics.Collections;

type
  TSorter<T> = class
  protected
    comparer: IComparer<T>;
  public
    constructor Create;
    destructor Destroy; override;
    procedure QSort(var data: array of T; l, r: integer);
  end;

implementation

constructor TSorter<T>.Create;
begin
  comparer := TComparer<T>.default;
end;

destructor TSorter<T>.Destroy;
begin
end;

procedure TSorter<T>.QSort(var data: array of T; l, r: integer);
var
  i, j: integer;
  x, y: T;
begin
  i := l;
  j := r;
  x := data[(l + r) div 2];
  while i <= j do
  begin
    while comparer.Compare(x, data[i]) > 0 do
      inc(i);
    while comparer.Compare(x, data[j]) < 0 do
      dec(j);
    if i <= j then
    begin
      y := data[i];
      data[i] := data[j];
      data[j] := y;
      inc(i);
      dec(j);
    end;
  end;
  if l < j then
    QSort(data, l, j);
  if i < r then
    QSort(data, i, r);
end;

end.
